/*
 * Copyright 2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.paboo.leaf.config;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.paboo.leaf.entity.LeafConfigEntity;
import org.paboo.leaf.utils.IOUtil;
import org.paboo.leaf.utils.JsonUtil;


/**
 * @author Leonard Woo
 */
@Slf4j
public class LeafConfiguration {

    private static final LeafConfiguration INSTANCE = new LeafConfiguration();
    public static LeafConfiguration getInstance() {
        return INSTANCE;
    }

    private LeafConfiguration() {
    }

    private static final String LEAF_CONFIG_FILE = "leaf.configFile";
    private static final String LEAF_DEFAULT_FILENAME = "leaf.json";

    public LeafConfigEntity loadConfig() {
        LeafConfigEntity conf = new LeafConfigEntity();
        String filepath = System.getProperty(LEAF_CONFIG_FILE, LEAF_DEFAULT_FILENAME);
        try {
            log.info("path: " + filepath);
            String json = IOUtil.readerToString(getReader(filepath));
            log.info(json);
            conf = JsonUtil.fromJson(json, LeafConfigEntity.class);
        } catch (IOException ex) {
            log.warn("File not found", ex);
        }
        return conf;
    }

    private final String groupId = "org.paboo";
    private final String artifactId = "leaf";

    private String version;

    private static final String[] BANNER = {"",
    "__________       ___.                   .____                  _____",
            "\\______   \\_____ \\_ |__   ____   ____   |    |    ____ _____ _/ ____\\",
            " |     ___/\\__  \\ | __ \\ /  _ \\ /  _ \\  |    |  _/ __ \\\\__  \\\\   __\\",
            " |    |     / __ \\| \\_\\ (  <_> |  <_> ) |    |__\\  ___/ / __ \\|  |",
            " |____|    (____  /___  /\\____/ \\____/  |_______ \\___  >____  /__|",
            "                \\/    \\/                        \\/   \\/     \\/"
    };
    private String project_name = " :: Paboo Leaf ::";

    public void printBanner(PrintStream out) {
        try {
            Model model = new MavenXpp3Reader().read(new InputStreamReader(getPomInputStream()));
            version = model.getVersion();

            String version = (this.version != null) ? " (v" + this.version + ")" : "";
            int maxLength = 0;
            for (int i = 0; i < BANNER.length; i++) {
                maxLength = BANNER[i].length();
               out.println(BANNER[i]);
            }

            StringBuilder padding = new StringBuilder();
            while (padding.length() < maxLength
                    - (version.length() + project_name.length())) {
                padding.append(" ");
            }
            out.println(project_name + padding.toString() + version);
            out.flush();
        } catch (Exception ex) {
            log.warn("BANNER load failed.", ex);
        }
    }

    private BufferedReader getReader(String name) throws FileNotFoundException{
        return IOUtil.loadStream(getPath(name));
    }

    private InputStream getPomInputStream() throws FileNotFoundException{
        InputStream is = this.getClass().getResourceAsStream(
            "/META-INF/maven/" + groupId + "/" + artifactId + "/pom.xml");
        if(is == null) {
            is = new FileInputStream("pom.xml");
        }
        return is;
    }

    private InputStream getPath(String name) throws FileNotFoundException{
        try {
            ClassLoader cl = this.getClass().getClassLoader();
            InputStream is = cl.getResourceAsStream(name);
            if (is == null) {
                try {
                    is = new FileInputStream(
                        Objects.requireNonNull(cl.getResource(name)).getPath());
                } catch (NullPointerException ex) {
                    is = null;
                }
            }
            if (is == null) {
                is = new FileInputStream(name);
            }
            return is;
        } catch (IOException ex) {
            log.warn("", ex);
            throw new FileNotFoundException();
        }
    }
}
